<?php
/**
 * @file name : project.php
 * @package   :
 * @author    : Vo Thanh Minh
 * @email     : <thanhminhld@yahoo.com - thanhminhld@gmail.com>
 * @copyright : 2011
 *
 */
if (!defined('BASEPATH')) {
    exit('No direct script access');
}

class Project extends Base_Controller
{
    /**
     * __construct
     * @access public
     * @param
     * @return
     */
    public function __construct()
    {
        parent::__construct();
    }
    /**
      * @function _remap
      *
      * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
      * @access public
      * @param  string
      * @return
      */
    public function _remap( $method )
    {
        switch ($method) {

            case 'add':
            case 'edit':
                $this->addEditProjects();
                break;

            case 'save':
                $this->createProject();
                break;

            default:
                $this->index();
        }
    }
    /**
     * @function index
     *
     * @author Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access private
     * @param
     * @return
     */
    private function index()
    {
        $controlName    = $this->input->get_post('c');
        /**
         * Get message when save insert or edit submit
         *
         */
        $msgBoxDisp = '';
        $clsType    = '';
        $clsIcon    = '';

        $messages = $this->getErrMsg($msgBoxDisp, $clsType, $clsIcon);
        /**
         * Get root modules list
         *
         */
        $this->load->model('Project_model', 'project_model');
        /**
         * Config for paging
         */
        $arrWhere = array();

        $this->load->library('pagination');
        $config['base_url'] = 'http://' . $_SERVER["HTTP_HOST"] . dirname($_SERVER["SCRIPT_NAME"])
                            . '/?c=' . $controlName;
        $totalRows = $this->project_model->getTotalRows($arrWhere);
        $config['total_rows'] = $totalRows;
        $config['per_page'] = 10;
        $config['num_links'] = 2;
        $config['page_query_string'] = TRUE;

        $config['first_link'] = 'First';
        $config['last_link'] = 'Last';
        $config['next_link'] = 'Next';
        $config['prev_link'] = 'Previous';
        $config['cur_tag_open'] = '&nbsp;<font color=#FF0000><strong>';
        $config['cur_tag_close'] = '</strong></font>';

        $this->pagination->initialize($config);
        $str_paging = $this->pagination->create_links();
        $this->msmarty->assign('paging',$str_paging);

        $offset = isset($_GET['per_page']) ? $_GET['per_page'] : 0;
        /**
         * End paging
         */
        $projectsList = $this->project_model->loadList($arrWhere, $config['per_page'], $offset);

        $data = array('urlControlName'  => '?c=' . $controlName,
                      'projectsList'    => $projectsList,
                      'messages'        => $messages,
                      'clsType'         => $clsType,
                      'clsIcon'         => $clsIcon,
                      'msgBoxDisp'      => $msgBoxDisp);

        $this->msmarty->view($controlName . '/project_manage', $data);
    }
    /**
     * @function addEditProjects
     *
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     * @param
     * @return
     */
    private function addEditProjects()
    {
        $controlName    = $this->input->get_post('c');
        $this->load->model('Project_model', 'project_model');
        $this->load->model('Modules_model', 'modules_model');
        /**
         * Get message when save insert or edit submit
         *
         */
        $msgBoxDisp = '';
        $clsType    = '';
        $clsIcon    = '';

        $messages = $this->getErrMsg($msgBoxDisp, $clsType, $clsIcon);

        $arrWhere = array('parent_id' => 0);
        $arrModule = $this->modules_model->loadList($arrWhere, 'all');
        $arrModule = array_chunk($arrModule, 4);

        $data = array('arrModule'  => $arrModule,
                      'actionForm' => '?c=' . $controlName . '&m=save',
                      'messages'   => $messages,
                      'clsType'    => $clsType,
                      'clsIcon'    => $clsIcon,
                      'msgBoxDisp' => $msgBoxDisp);
        $this->msmarty->view($controlName . '/project_add', $data);
    }
    /**
     * @function  createProject
     *
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     *
     */
    private function createProject()
    {
        $controlName    = $this->input->get_post('c');
        $data           = array();
        if ($_SERVER['REQUEST_METHOD']==='POST') {
            $data['p_name'] = trim($this->input->post('p_name'));
            $data['m_id']   = $this->input->post('m_name');
        }
        $templateKind = $this->input->post('templ');
        /**
         * Load lang to show msg
         */
        $this->lang->load('success', $this->lang_tag);
        $this->lang->load('error', $this->lang_tag);

        $errCode = FALSE;

        if (preg_match('/[^a-z]/', $data['p_name'])) { // Not alpha character
            $this->messages->add($this->lang->line('project_name_err'), 'error');
            $errCode = TRUE;
        }
        if (count($data['m_id']) <= 0) {
            $this->messages->add($this->lang->line('project_module_err'), 'error');
            $errCode = TRUE;
        }
        if (! preg_match('/^S|T$/', $templateKind)) {
            $this->messages->add($this->lang->line('template_admin_invaid'), 'error');
            $errCode = TRUE;
        }
        if ($errCode == TRUE) {
            defaultPage($controlName . '&m=add');
            exit();
        }
        /**
         * Create Project folder
         */
        $ret = $this->createProjectFolder($data['p_name'], $errCode);
        if ($ret == FALSE || $errCode == TRUE) {
            defaultPage($controlName . '&m=add');
            exit();
        }
        /**
         * Copy system folder from basicSource folder to project folder
         */
        $source = PROJECT_PATH . 'basicSource/system/';
        $destination = PROJECT_PATH . $data['p_name'];
        $ret = $this->copyFileFolder($errCode, $source, $destination, '-R');
        if ($ret == FALSE || $errCode == TRUE) {
            defaultPage($controlName . '&m=add');
            exit();
        }
        /**
         * Copy administrator folder
         */
        if ($templateKind == 'T') {
            $source = PROJECT_PATH . 'basicSource/administratorTitanium';
        } else {
            $source = PROJECT_PATH . 'basicSource/administrator';
        }
        $destination = PROJECT_PATH . $data['p_name'];
        $ret = $this->copyFileFolder($errCode, $source, $destination, '-R');
        if ($ret == FALSE || $errCode == TRUE) {
            defaultPage($controlName . '&m=add');
        }
        /**
         * Rename folder administratorTitanium
         */
        if ($templateKind == 'T') {
            exec('rm -R ' . PROJECT_PATH . $data['p_name'] . '/administratorTitanium '
                 . PROJECT_PATH . $data['p_name'] . '/administrator', $outPut);
            if (count($outPut) > 0) {
                foreach ($outPut as $k => $err) {
                    $this->messages->add($err, 'error');
                }
                defaultPage($controlName . '&m=add');
            }
        }
        /**
         * Set permission
         */
        $path = PROJECT_PATH . $data['p_name'] . '/administrator';
        $resource = 'Readme';
        $this->setPermission($errCode, $path, $resource, '-R', '0777');
        /**
         * Copy application folder
         */
        $source = PROJECT_PATH . 'basicSource/application';
        $destination = PROJECT_PATH . $data['p_name'];
        $this->copyFileFolder($errCode, $source, $destination, '-R');
        /**
         * Copy file index.php and .htaccess
         */
        $source = PROJECT_PATH . 'basicSource/index.php';
        $destination = PROJECT_PATH . $data['p_name'];
        $this->copyFileFolder($errCode, $source, $destination);

        $source = PROJECT_PATH . 'basicSource/.htaccess';
        $destination = PROJECT_PATH . $data['p_name'];
        $this->copyFileFolder($errCode, $source, $destination);
        /**
         * Create modules structure table (SQL)
         */
        $arrModule = $this->modules_model->loadListIn('m_id', $data['m_id']);

        // Get group module
        $arrGroupMode = $this->module_group_model->loadList(array(), 'all');

        $this->createSqlFile($arrModule, $data['p_name']);
        /**
         * Create language folder
         */
        $proj_lang = $this->input->post('proj_lang');
        $proj_lang = substr($proj_lang, 0, -1);
        $proj_lang = explode(',', $proj_lang);

        // Set permission to administrator/application/language folder
        $path = PROJECT_PATH . $data['p_name'] . '/administrator/application';
        $resource = 'language';
        $this->project_model->setPermission($errCode, $path, $resource, '-R', '0777');
        $ret = '';
        foreach ($proj_lang as $pLang) {
            $path = PROJECT_PATH . $data['p_name'] . '/administrator/application/language';
            $ret = $this->createLanguageFolder($path, $pLang, $errCode);
            if ($ret == FALSE) {
                break;
            }
            // Ghi gia tri default cho cac ngon ngu
            $ret = $this->writeLangDefaultVal($errCode, $data['p_name'], $pLang);
            if ($ret == FALSE) {
                break;
            }
        }
        if ($ret == FALSE || $errCode == TRUE) {
            defaultPage($controlName . '&m=add');
            exit();
        }
        /**
         * Assign menu for administrator
         */
        $this->load->model('menuheader_model');
        $this->menuheader_model->assignMenuAdministrator($arrModule, $data['p_name']);
        /**
         * Create menu header file administrator
         */
        $this->menuheader_model->createMenuHeaderAdmin($arrGroupMode, $arrModule, $data['p_name'], $templateKind);
        /**
         * Create model file for module
         */
        $this->load->model('filemodel_model');
        $this->filemodel_model->createModelFile($arrModule, $data['p_name'], $templateKind);
        /**
         * Create controller file of modules
         */
        $this->load->model('filecontroller_model');
        $this->filecontroller_model->createControlerModules($arrModule, $data['p_name']);
        /**
         * Create template for modules
         */
        $this->load->model('filetemplate_model');
        $this->filetemplate_model->createTemplateModules($errCode, $arrModule, $data['p_name']);
        /**
         * Delete .svn file / folder
         */
        exec('find ' . PROJECT_PATH . $data['p_name'] . ' -name \'.svn\' > /opt/lampp/htdocs/test/rmfile.txt');
        $fp = fopen('/opt/lampp/htdocs/test/rmfile.txt', 'r');
        if ($fp) {

            while( ! feof($fp)) {
                $file = fgets($fp);
                exec('rm -R ' . $file);
            }

        }
        fclose($fp);
        /**
         * Copy this project to htdocs and set permission templates_c in administrator folder
         */
        $pathSourceCp = '/opt/lampp/htdocs/projectTool/';
        $pathDesCp    = '/opt/lampp/htdocs/';
        $outPut = array();
        exec('mv -T ' . PROJECT_PATH . $data['p_name'] . ' ' . $pathDesCp . $data['p_name'], $outPut);
        if (count($outPut) > 0) {
            foreach ($outPut as $k => $err) {
                $this->messages->add($err, 'error');
            }
            $errCode = TRUE;
        }
        exec('chmod -R 0777 ' . $pathDesCp . $data['p_name'] . '/administrator/application/templates_c');
        /**
         * Save to db this project
         */
        $data['m_id'] = implode(',', $data['m_id']);

        $this->db->trans_begin();
        $ret = $this->project_model->storeTblWithoutLang($data, 'id', false);
        if ($ret == FALSE) {
            $this->messages->add($this->lang->line('db_insert_update_err'), 'error');
            // Rollback transaction
            $this->db->trans_rollback();
        } else {
            $this->messages->add($this->lang->line('db_insert_success'), 'success');
            // Commit transaction
            $this->db->trans_commit();
        }
        /**
         * Check error
         */
        if ($errCode == TRUE) {
            defaultPage($controlName . '&m=add');
            return false;
        }
        defaultPage($controlName);
    }
    /**
     * writeLangDefaultVal
     *
     */
    private function writeLangDefaultVal(&$errCode, $projectName, $langSql)
    {
        if ($projectName == NULL || $langSql == NULL) {
            return FALSE;
        }
        $filename = PROJECT_PATH . $projectName . '/administrator/Readme/db.sql';
        if ( ! file_exists($filename)) {
            return FALSE;
        }
        $path = PROJECT_PATH . $projectName . '/administrator/Readme';
        $ret  = $this->project_model->setPermission($errCode, $path, 'db.sql', '', '0777');
        if ( ! $ret) {
            return FALSE;
        }

        $sql = '';
        switch ($langSql) {
            case 'en':
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('English', 'en.png', 1, 1, 'en');";
                break;

            case 'jp':
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('日本', 'jp.png', 1, 1, 'jp');";
                break;

            case 'fr':
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('Française', 'fr.png', 1, 1, 'fr');";
                break;

            case 'kr':
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('한국어', 'kr.png', 1, 1, 'kr');";
                break;

            case 'cn':
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('中文', 'cn.png', 1, 1, 'cn');";
                break;

            case 'de':
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('Deutsch', 'de.png', 1, 1, 'de');";
                break;

            default: // for vn
                $sql = 'INSERT INTO `tbl_lang`(`name`, `flg`, `status`, `default`, `tag`) '
                     . "VALUES('Tiếng Việt', 'vn.png', 1, 1, 'vn');";
        }
        $sql = "\n" . $sql;
        $fpLang = fopen($filename, 'a+'); //Open for reading and writing; place the file pointer at the end of the file.
        if ( $fpLang ) {
            fwrite($fpLang, $sql);
        }
        fclose($fpLang);

        return TRUE;
    }
    /**
     * @function createLanguageFolder
     *
     * Mac dinh $type = 'admin' de tao thu muc language cho phan quan tri
     *
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     * @param     string $path
     * @param     string $type
     */
    private function createLanguageFolder($path, $pLang, &$errCode, $type = 'admin')
    {
        if (strlen($path) <= 0) {
            $errCode = TRUE;
            $this->messages->add($this->lang->line('path_lang_folder_invalid'), 'error');
            return FALSE;
        }
        if ( ! is_writeable($path)) {
            $this->messages->add(sprintf($this->lang->line('folder_not_writeable'), $path . '/' . $pLang), 'error');
            return FALSE;
        }
        if (function_exists('realpath') && @realpath($path . '/' . $pLang) == FALSE) {
            $outPut = array();
            exec('mkdir --mode=0777 ' . $path . '/' . $pLang, $outPut);
            if (count($outPut) > 0) {
                foreach ($outPut as $k => $err) {
                    $this->messages->add($err, 'error');
                }
                $errCode = TRUE;
                return FALSE;
            }
            /**
             * Copy file language default
             */
            $langPath = APPPATH . 'lang_admin_default/';
            $langDir = $this->mscandir->getScanDir($langPath);
            if ( ! empty($langDir)) {
                foreach ($langDir as $langFile) {
                    $this->copyFileFolder($errCode, $langPath . $langFile, $path . '/' . $pLang);
                }
            }
        }
        return TRUE;
    }
    /**
     * @function createSqlFile
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     * @param     string
     * @param     boolean
     */
    private function createSqlFile($arrModule = array(), $projectName)
    {
        $filename = PROJECT_PATH . $projectName . '/administrator/Readme/db.sql';
        if (file_exists($filename)) {
            exec('rm -f ' . $filename);
        }
        $fp = fopen($filename, 'x');
        foreach ($arrModule as $key => $modObj) {
            $strTblLabel = '/*Table structure for table `%s` - %s*/';
            $strTblLabel = sprintf($strTblLabel, $modObj->m_name, $modObj->m_discr);
            if (!is_null($modObj->m_tbl_struct) && strlen($modObj->m_tbl_struct) > 0 && $modObj->m_relation == 'N') {
                // for single module
                fwrite($fp, $strTblLabel . "\n\n");
                fwrite($fp, $modObj->m_tbl_struct . "\n\n");
                fwrite($fp, $modObj->m_default_val . "\n\n");
            } else if ($modObj->m_relation == 'Y') {
                // for relation module
                if (!is_null($modObj->m_tbl_struct) && strlen($modObj->m_tbl_struct) > 0) {
                    fwrite($fp, $strTblLabel . "\n\n");
                    fwrite($fp, $modObj->m_tbl_struct . "\n\n");
                    fwrite($fp, $modObj->m_default_val . "\n\n");
                }
                // Get relation module
                $relationModule = $this->modules_model->loadListIn('parent_id', $modObj->m_id);
                foreach ($relationModule as $k => $relMode) {
                    $strTblLabel = '/*Table structure for table `%s` - %s*/';
                    $strTblLabel = sprintf($strTblLabel, $relMode->m_name, $relMode->m_discr);
                    if (!is_null($relMode->m_tbl_struct) && strlen($relMode->m_tbl_struct) > 0) {
                        fwrite($fp, $strTblLabel . "\n\n");
                        fwrite($fp, $relMode->m_tbl_struct . "\n\n");
                        fwrite($fp, $modObj->m_default_val . "\n\n");
                    }
                }
            }
        }
        fclose($fp);
    }
    /**
     * @function copyFileFolder
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     * @param     string
     * @param     boolean
     */
    private function copyFileFolder(&$errCode, $source, $destination, $option = '', $mode = '')
    {
        if ( ! is_writeable($destination)) {
            $this->messages->add(sprintf($this->lang->line('can_not_copy_file_folder'), $source), 'error');
            return FALSE;
        }
        if ($option == '-R' || $option == '-r') { // folder
            if (function_exists('realpath') && @realpath($source) != FALSE) {
                $outPut = array();
                exec('cp ' . $option . ' ' . $source . ' ' . $destination, $outPut);
                if (count($outPut) > 0) {
                    foreach ($outPut as $k => $err) {
                        $this->messages->add($err, 'error');
                    }
                    $errCode = TRUE;
                    return FALSE;
                }
            }
        } else { // File
            if (file_exists($source)) {
                $outPut = array();
                exec('cp ' . $source . ' ' . $destination, $outPut);
                if (count($outPut) > 0) {
                    foreach ($outPut as $k => $err) {
                        $this->messages->add($err, 'error');
                    }
                    $errCode = TRUE;
                    return FALSE;
                }
            }
        }
        // set permission
        return TRUE;
    }
    /**
     * @function createProjectFolder
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     * @param     string
     * @param     boolean
     */
    private function createProjectFolder($projectName, &$errCode)
    {
        if (function_exists('realpath') && @realpath(PROJECT_PATH . $projectName) == FALSE) {
            if ( ! is_writeable(PROJECT_PATH)) {
                $this->messages->add(sprintf($this->lang->line('folder_not_writeable'), $projectName), 'error');
                return FALSE;
            }
            $outPut = array();
            exec('mkdir --mode=0777 ' . PROJECT_PATH . $projectName, $outPut);
            if (count($outPut) > 0) {
                foreach ($outPut as $k => $err) {
                    $this->messages->add($err, 'error');
                }
                $errCode = TRUE;
                return FALSE;
            }
        }

        return TRUE;
    }
    /**
     * @function getErrMsg
     *
     * @author   Vo Thanh Minh <thanhminhld@yahoo.com - thanhminhld@gmail.com>
     * @access   private
     * @param    string $msgBoxDisp, $clsType, $clsIcon
     * @return   array
     */
    private function getErrMsg(&$msgBoxDisp, &$clsType, &$clsIcon)
    {
        $messages = $this->messages->get();

        if (!is_array($messages)) {
            $messages = array();
            $msgBoxDisp = 'none;';
        } else {
            foreach($messages as $type => $message) {
                if(!empty($message)) {
                    if ($type == 'error') {
                        $clsType = $type;
                        $clsIcon = 'errorIcon';
                    } else if ($type == 'success') {
                        $clsType = $type;
                        $clsIcon = 'successIcon';
                    }
                    break;
                }
            }
        }
        $this->messages->clear();
        return $messages;
    }
}
